package chapter8;

import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Chapter8Demo2 {
    public static void main(String[] args) {
        //listDemo();
        //hashDemo();
        //setDemo();
        //sortedSetDemo();
        geoDemo();
    }

    /**
     * List数据结构演示
     * 该方法用于演示如何使用Jedis操作List数据结构，包括插入和查询操作
     */
    private static void listDemo() {
        // 创建Jedis对象，连接本地Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);

        // 向List的尾部添加元素
        jedis.rpush("001", "Peter");
        jedis.rpush("001", "15");
        jedis.rpush("001", "Male");

        // 检查Key是否存在
        if (jedis.exists("001")) {
            // 如果Key存在，打印List中的每个元素
            System.out.println(jedis.lindex("001", 0));
            System.out.println(jedis.lindex("001", 1));
            System.out.println(jedis.lindex("001", 2));
        } else {
            // 如果Key不存在，打印提示信息
            System.out.println("Key does not exist,get from db");
        }
    }

    /**
     * 示例如何使用Jedis操作Hash数据类型
     * 该方法连接到本地的Redis服务器，使用HSET命令向两个员工ID（Emp002和Emp003）添加信息，
     * 并使用HGET命令获取这些信息
     */
    static void hashDemo() {
        // 创建Jedis实例，连接到本地Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);

        // 向Emp002这个Hash中设置name、age和gender字段
        jedis.hset("Emp002", "name", "Peter");
        jedis.hset("Emp002", "age", "15");
        jedis.hset("Emp002", "gender", "Male");

        // 获取并打印Emp002的name和age字段
        System.out.println(jedis.hget("Emp002", "name"));
        System.out.println(jedis.hget("Emp002", "age"));

        // 使用Map封装Emp003的信息，然后一次性设置到Redis中
        Map<String, String> emp03 = new HashMap<>();
        emp03.put("name", "farb");
        emp03.put("age", "18");
        emp03.put("gender", "Male");
        jedis.hset("Emp003", emp03);

        // 再次获取并打印Emp002和Emp003的name字段，展示数据一致性
        System.out.println(jedis.hget("Emp003", "name"));
        System.out.println(jedis.hget("Emp003", "age"));
    }

    /**
     * 使用Jedis操作Redis的Set数据结构的演示方法
     * 该方法展示了如何向Set中添加元素，并打印出Set中的所有元素
     */
    static void setDemo() {
        // 创建Jedis对象，连接本地的Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);
        // 向Set“bonusId”中添加元素“1”、“2”、“3”、“4”、“1”，注意重复元素会被忽略
        jedis.sadd("bonusId", "1", "2", "3", "4", "1");
        // 打印Set“bonusId”中的所有元素
        System.out.println(jedis.smembers("bonusId"));
    }

    /**
     * 示范使用Sorted Set数据结构的操作
     * 该方法主要展示了如何在Redis中使用Jedis操作Sorted Set，包括添加成员和获取排序范围
     */
    static void sortedSetDemo() {
        // 创建Jedis对象，连接本地的Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);
        // 向Sorted Set "emps"中添加成员"Peter"，分数为1.0
        jedis.zadd("emps", 1.0, "Peter");
        // 向Sorted Set "emps"中添加成员"Jane"，分数为3.0
        jedis.zadd("emps", 3.0, "Jane");
        // 向Sorted Set "emps"中添加成员"Mike"，分数为2.0
        jedis.zadd("emps", 2.0, "Mike");
        // 打印Sorted Set "emps"中所有成员，验证添加操作的结果
        System.out.println(jedis.zrange("emps", 0, -1));

        // 根据分数范围查询并打印Sorted Set "emps"中的成员及其分数，分数范围为2.0到3.0
        System.out.println(jedis.zrangeByScoreWithScores("emps", 2.0, 3.0));
    }

    /**
     * 地理位置演示函数
     * 该函数演示了如何使用Jedis操作Redis中的地理位置数据
     * 主要包括添加地理位置数据、获取位置信息、查询一定半径内的地理位置以及计算两点间的距离
     */
    static void geoDemo() {
        // 创建Jedis对象，连接本地的Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);

        // 向Redis中添加地理位置数据，包括经度、纬度和位置标识
        jedis.geoadd("geo", 120.52, 30.40, "pos1");
        jedis.geoadd("geo", 120.52, 31.53, "pos2");
        jedis.geoadd("geo", 122.12, 30.40, "pos3");
        jedis.geoadd("geo", 122.12, 31.53, "pos4");

        // 打印所有位置的地理坐标
        System.out.println(jedis.geopos("geo", "pos1", "pos2", "pos3", "pos4"));

        // 查询以给定经纬度为中心，指定半径内的地理位置
        List<GeoRadiusResponse> geoList = jedis.georadius("geo", (long) 120.52, 30.40, 200, GeoUnit.KM);
        for (GeoRadiusResponse res : geoList) {
            // 打印查询到的地理位置
            System.out.println(res.getMemberByString());
        }

        // 计算两个地理位置之间的距离
        Double distance = jedis.geodist("geo", "pos1", "pos2", GeoUnit.KM);
        // 打印计算得到的距离
        System.out.println(distance);
    }

}
